package org.springblade.modules.admin.service.erp.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tenant.annotation.TenantIgnore;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.admin.dto.ErpTransferStatusDTO;
import org.springblade.modules.admin.dto.erp.PartnerCloudTableFilterDTO;
import org.springblade.modules.admin.dto.erp.PartnerCloudTableItemDTO;
import org.springblade.modules.admin.dto.erp.PartnerCloudTableSaveOrUpdateDTO;
import org.springblade.modules.admin.dto.erp.serivce.BuyingLeadsDTO;
import org.springblade.modules.admin.dto.erp.serivce.MultiplyBuyingLeadsDTO;
import org.springblade.modules.admin.dto.erp.serivce.PartnerCloudPartsSkuMessageDTO;
import org.springblade.modules.admin.dto.erp.serivce.PartnerCloudPartsSkuSyncDTO;
import org.springblade.modules.admin.entity.MaintainContractType;
import org.springblade.modules.admin.enums.TaskStatusEnum;
import org.springblade.modules.admin.enums.erp.ERPTableEnum;
import org.springblade.modules.admin.enums.erp.options.BuyingLeadsTypeEnum;
import org.springblade.modules.admin.enums.erp.options.SalesOrderStatusEnum;
import org.springblade.modules.admin.enums.erp.tables.*;
import org.springblade.modules.admin.service.IMaintainContractTypeService;
import org.springblade.modules.admin.service.IMaintainPartService;
import org.springblade.modules.admin.service.MaintainPartsWorkService;
import org.springblade.modules.admin.service.erp.IPartnerCloudPartsService;
import org.springblade.modules.admin.service.erp.IPartnerCloudSpaceTableService;
import org.springblade.modules.admin.vo.erp.service.BuyingLeadsVO;
import org.springblade.modules.admin.vo.erp.service.DeliveryVO;
import org.springblade.modules.admin.vo.erp.service.SalesOrderSearchVO;
import org.springblade.modules.admin.vo.erp.service.ShipmentDetailVO;
import org.springblade.modules.admin.vo.erp.tables.PartnerCloudTableItemListVO;
import org.springblade.modules.admin.vo.erp.tables.PartnerCloudTableItemVO;
import org.springblade.modules.admin.vo.parts.PartsWorkDetailVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: Sharry
 * @createTime: 2024-12-26 15:25
 * @version: Version-1.0
 */
@Slf4j
@Service
public class PartnerCloudPartsServiceImpl implements IPartnerCloudPartsService {

	private IPartnerCloudSpaceTableService erpService;

	@Autowired
	public void setErpService(IPartnerCloudSpaceTableService erpService){
		this.erpService = erpService;
	}

	private IMaintainPartService maintainPartService;

	@Autowired
	public void setMaintainPartService(IMaintainPartService maintainPartService){
		this.maintainPartService = maintainPartService;
	}

	private MaintainPartsWorkService partsWorkService;

	@Autowired
	public void setPartsWorkService(MaintainPartsWorkService partsWorkService){
		this.partsWorkService = partsWorkService;
	}

	private IMaintainContractTypeService maintainContractTypeService;

	@Autowired
	public void setMaintainContractTypeService(IMaintainContractTypeService maintainContractTypeService){
		this.maintainContractTypeService = maintainContractTypeService;
	}

	/**
	 * 1:N 同步采购订单到伙伴云ERP
	 * @param planId 工单id
	 */
	@Override
	@TenantIgnore
	public void syncMultiplyPurchase(Long planId, String tenantId) {
		// 1. 根据工单id查询同步所需字段
		List<MultiplyBuyingLeadsDTO> purchaseList = this.selectMultiplyPurchaseByPlanId(planId,tenantId);
		// 2. 组装同步条件
		if(Func.isNotEmpty(purchaseList)){
			PartnerCloudTableSaveOrUpdateDTO saveDTO = new PartnerCloudTableSaveOrUpdateDTO();
			// 2.1 固定信息：表id、根据联合主键id新增或更新
			saveDTO.setTable_id(ERPTableEnum.BUYING_LEADS.getTableId());
			List<String> updateFields = new ArrayList<>();
			updateFields.add(BuyingLeadsEnum.UNITED_ID.getFieldId());
			saveDTO.setUpdate_by_fields(updateFields);
			// 2.2 遍历purchaseList，组装同步数据
			List<PartnerCloudTableItemDTO> items = new ArrayList<>();
			purchaseList.forEach(p -> {
				PartnerCloudTableItemDTO item = new PartnerCloudTableItemDTO();
				Map<String,Object> fields = new HashMap<>(20);
				fields.put(BuyingLeadsEnum.UNITED_ID.getFieldId(), p.getUnitedId());
				fields.put(BuyingLeadsEnum.BUYING_LEADS_STATUS.getFieldId(),p.getBuyingLeadsStatus());
				fields.put(BuyingLeadsEnum.SALES_LEADS_STATUS.getFieldId(),p.getSaleLeadsStatus());
				fields.put(BuyingLeadsEnum.TYPE.getFieldId(),p.getType());
				fields.put(BuyingLeadsEnum.PARTS_TASK_ID.getFieldId(),p.getPartsTaskId());
				// 收货人信息，均可能为空，需要做判断处理
				String receiver = p.getReceiver();
				if(StringUtil.isNotBlank(receiver)){
					fields.put(BuyingLeadsEnum.RECEIVER.getFieldId(),receiver);
				}
				String phone = p.getReceiverPhone();
				if(StringUtil.isNotBlank(phone)){
					fields.put(BuyingLeadsEnum.RECEIVER_PHONE.getFieldId(),phone);
				}
				String receiverAddress = p.getReceiverAddress();
				if(StringUtil.isNotBlank(receiverAddress)){
					fields.put(BuyingLeadsEnum.RECEIVER_ADDRESS.getFieldId(),receiverAddress);
				}
				// 是否为质保梯
				List<String> chargeElevator = p.getChargeElevator();
				if(Func.isNotEmpty(chargeElevator)){
					fields.put(BuyingLeadsEnum.CHARGE_ELEVATOR.getFieldId(),chargeElevator);
				}
				// 两个附件：配件清单和附件
				if(Func.isNotEmpty(p.getPartsList())){
					fields.put(BuyingLeadsEnum.PARTS_LIST.getFieldId(),p.getPartsList());
				}
				if(Func.isNotEmpty(p.getAttachment())){
					fields.put(BuyingLeadsEnum.ATTACHMENT.getFieldId(),p.getAttachment());
				}
				fields.put(BuyingLeadsEnum.BUILDING_NAME.getFieldId(),p.getBuildingName());
				fields.put(BuyingLeadsEnum.ELEVATOR_ADDRESS.getFieldId(),p.getElevatorAddress());
				// 2025-07 改成关联配件数量以及备注
				if(Func.isNotEmpty(p.getFinallySkuPartsInfo())){
					JSONObject finallySkuPartsInfo = JSONObject.parseObject(p.getFinallySkuPartsInfo(),JSONObject.class);
					if(Func.isNotEmpty(finallySkuPartsInfo)){
						if(finallySkuPartsInfo.containsKey("num")){
							String num = finallySkuPartsInfo.getString("num");
							Double numDouble = Double.parseDouble(num);
							fields.put(BuyingLeadsEnum.REQUIREMENT_QUANTITY.getFieldId(),numDouble);
						}
						if(finallySkuPartsInfo.containsKey("desc")){
							fields.put(BuyingLeadsEnum.REMARK.getFieldId(),finallySkuPartsInfo.get("desc"));
						}
					}
				}
				String requirementDescription = p.getRequirementDescription();
				if(StringUtil.isNotBlank(requirementDescription)){
					fields.put(BuyingLeadsEnum.REQUIREMENT_DESCRIPTION.getFieldId(),requirementDescription);
				}
				fields.put(BuyingLeadsEnum.APPLY_DATE.getFieldId(),p.getApplyDate());
				fields.put(BuyingLeadsEnum.APPLY_USER.getFieldId(),p.getApplyUser());
				fields.put(BuyingLeadsEnum.CUSTOMER.getFieldId(),p.getCustomer());
				fields.put(BuyingLeadsEnum.BUILDING_ID.getFieldId(),p.getProjectId());
				if(Func.isNotEmpty(p.getRelationParts())){
					fields.put(BuyingLeadsEnum.RELATION_PARTS.getFieldId(),p.getRelationParts());
				}
				if(Func.isNotBlank(p.getContractMaintainTypeName())){
					fields.put(BuyingLeadsEnum.MAINTAIN_TYPE_DESCRIPTION.getFieldId(),p.getContractMaintainTypeName());
				}
				// 2025-02-14 新增 即将新增电梯品牌、唯一识别码、停梯状态字段
				if(Func.isNotBlank(p.getElevatorBrand())){
					fields.put(BuyingLeadsEnum.ELEVATOR_BRAND.getFieldId(),p.getElevatorBrand());
				}
				if(Func.isNotBlank(p.getElevatorNum())){
					fields.put(BuyingLeadsEnum.ELEVATOR_NUM.getFieldId(),p.getElevatorNum());
				}
				if(Func.isNotBlank(p.getElevatorStatus())){
					fields.put(BuyingLeadsEnum.ELEVATOR_STATUS.getFieldId(),p.getElevatorStatus());
				}
				item.setFields(fields);
				items.add(item);
			});
			saveDTO.setItems(items);
			boolean purchaseResult = erpService.saveOrUpdateByFields(saveDTO);
			log.warn("传到erp结果：{}", purchaseResult);
		}
	}

	@Override
	public List<MultiplyBuyingLeadsDTO> selectMultiplyPurchaseByPlanId(Long planId, String tenantId) {
		// 1.  查询可查询的同步字段
		List<BuyingLeadsVO> buyingLeadsVOList = maintainPartService.selectBuyingLeadsListByPlanId(planId,tenantId);
		List<MultiplyBuyingLeadsDTO> multiplyBuyingLeadsDTOList = new ArrayList<>();
		// 2. 数据封装、处理
		if(Func.isNotEmpty(buyingLeadsVOList)){
			buyingLeadsVOList.forEach(b -> {
				String contractTypeHistoryInfoString = b.getContractTypeHistoryInfo();
				// 将 contractTypeHistoryInfoString 转换成 MaintainContractType 对象
				if(!Func.isNull(contractTypeHistoryInfoString)){
					MaintainContractType contractTypeHistoryInfo = JSONObject.parseObject(contractTypeHistoryInfoString, MaintainContractType.class);
					if (contractTypeHistoryInfo != null) {
						List<MaintainContractType> list = new ArrayList<>(1);
						list.add(contractTypeHistoryInfo);
						List<MaintainContractType> maintainContractTypes = maintainContractTypeService.contractTypeList(list);
						String name = maintainContractTypes.get(0).getName();
						b.setContractMaintainTypeName(name);
					}
				}
				MultiplyBuyingLeadsDTO multiplyBuyingLeadsDTO = this.purchaseDataTransfer(b);
				multiplyBuyingLeadsDTOList.add(multiplyBuyingLeadsDTO);
			});
		}
		return multiplyBuyingLeadsDTOList;
	}

	public MultiplyBuyingLeadsDTO purchaseDataTransfer(BuyingLeadsVO buyingLeadsVO){
		MultiplyBuyingLeadsDTO multiplyBuyingLeadsDTO = new MultiplyBuyingLeadsDTO();
		// 1. 固定字段传参
		List<String> buyingLeadsStatus = new ArrayList<>();
		buyingLeadsStatus.add(BuyingLeadsTypeEnum.BUYING_LEADS_APPLYING.getId());
		multiplyBuyingLeadsDTO.setBuyingLeadsStatus(buyingLeadsStatus);
		List<String> saleLeadsStatus = new ArrayList<>();
		saleLeadsStatus.add(BuyingLeadsTypeEnum.SALES_LEADS_QUOTING.getId());
		multiplyBuyingLeadsDTO.setSaleLeadsStatus(saleLeadsStatus);
		List<String> type = new ArrayList<>();
		type.add(BuyingLeadsTypeEnum.TYPE_APPLY.getId());
		multiplyBuyingLeadsDTO.setType(type);
		multiplyBuyingLeadsDTO.setReceiver(buyingLeadsVO.getReceiver());
		multiplyBuyingLeadsDTO.setReceiverPhone(buyingLeadsVO.getReceiverPhone());
		multiplyBuyingLeadsDTO.setReceiverAddress(buyingLeadsVO.getReceiverAddress());
		multiplyBuyingLeadsDTO.setPartsTaskId(buyingLeadsVO.getPartsTaskId());
		multiplyBuyingLeadsDTO.setBuildingName(buyingLeadsVO.getBuildingName());
		multiplyBuyingLeadsDTO.setElevatorAddress(buyingLeadsVO.getElevatorAddress());
		multiplyBuyingLeadsDTO.setRequirementQuantity(buyingLeadsVO.getRequirementQuantity());
		multiplyBuyingLeadsDTO.setRequirementDescription(buyingLeadsVO.getRequirementDescription());
		multiplyBuyingLeadsDTO.setApplyUser(buyingLeadsVO.getApplyUser());
		multiplyBuyingLeadsDTO.setElevatorAddress(buyingLeadsVO.getElevatorAddress());
		multiplyBuyingLeadsDTO.setCustomer(buyingLeadsVO.getCustomer());
		// 2025-02 新增 即将新增电梯品牌、唯一识别码、停梯状态字段
		multiplyBuyingLeadsDTO.setElevatorBrand(buyingLeadsVO.getElevatorBrand());
		multiplyBuyingLeadsDTO.setElevatorNum(buyingLeadsVO.getElevatorNum());
		multiplyBuyingLeadsDTO.setElevatorStatus(buyingLeadsVO.getElevatorStatus());
		multiplyBuyingLeadsDTO.setFinallySkuPartsInfo(buyingLeadsVO.getFinallySkuPartsInfo());
		if(Func.isNotBlank(buyingLeadsVO.getContractMaintainTypeName())){
			multiplyBuyingLeadsDTO.setContractMaintainTypeName(buyingLeadsVO.getContractMaintainTypeName());
		}else{
			multiplyBuyingLeadsDTO.setContractMaintainTypeName(buyingLeadsVO.getMaintainTypeName());
		}
		// 是否为质保梯
		String isQuaGuarantee = buyingLeadsVO.getIsQuaGuarantee();
		if(Func.isNotBlank(isQuaGuarantee) || "1".equals(isQuaGuarantee) || "0".equals(isQuaGuarantee)){
			List<String> chargeElevator = new ArrayList<>();
			if("1".equals(isQuaGuarantee)){
				chargeElevator.add(BuyingLeadsTypeEnum.IS_QUANTITY.getId());
			}else if("0".equals(isQuaGuarantee)) {
				chargeElevator.add(BuyingLeadsTypeEnum.NOT_QUANTITY.getId());
			}
			multiplyBuyingLeadsDTO.setChargeElevator(chargeElevator);
		}
		// 2. 关联字段查询伙伴云获取
		// 配件清单
		if(Func.isNotBlank(buyingLeadsVO.getHUrl())){
			log.warn("开始处理并同步配件清单附件：{}", buyingLeadsVO.getHUrl());
			List<Map<String, String>> partsList = new ArrayList<>();
			Map<String, String> fileMap = new HashMap<>();
			String hUrl = buyingLeadsVO.getHUrl();
			String file_id = uploadFile(hUrl);
			fileMap.put("file_id", file_id);
			multiplyBuyingLeadsDTO.setPartsList(partsList);
			if(Func.isBlank(buyingLeadsVO.getHName())){
				log.warn("配件清单文件名数据不全{}", buyingLeadsVO.getHUrl());
				buyingLeadsVO.setHName("配件清单");
			}
			fileMap.put("name", buyingLeadsVO.getHName());
			partsList.add(fileMap);
			multiplyBuyingLeadsDTO.setPartsList(partsList);
		}
		// 附件
		String attachment = buyingLeadsVO.getAttachment();
		if(Func.isNotBlank(attachment)){
			log.warn("开始处理并同步附件：{}", attachment);
			List<String> urls = new ArrayList<>();
			List<String> requireKeys = new ArrayList<>();
			requireKeys.add("url");
			requireKeys.add("type");
			String requireTypeKey = "image";
			JSONArray attachmentArray = JSONArray.parseArray(attachment);
			attachmentArray.forEach(a -> {
				JSONObject attachmentObj = JSONObject.parseObject(a.toString());
				if(!attachmentObj.keySet().containsAll(requireKeys)){
					log.warn("附件数据不全：{}", attachmentObj);
					return;
				}
				String attachmentType = attachmentObj.getString("type");
				if(!requireTypeKey.equals(attachmentType)){
					return;
				}
				urls.add(attachmentObj.getString("url"));
			});
			if(Func.isNotEmpty(urls)){
				List<Map<String, String>> attachmentList = new ArrayList<>();
				urls.forEach(u -> {
					String fileName = u.substring(u.lastIndexOf("/")+1);
					String file_id = uploadFile(u);
					log.warn("上传配件附件：{}", file_id);
					Map<String, String> attachmentMap = new HashMap<>();
					attachmentMap.put("file_id", file_id);
					attachmentMap.put("name", fileName);
					attachmentList.add(attachmentMap);
				});
				multiplyBuyingLeadsDTO.setAttachment(attachmentList);
			}
		}
		// 项目关联
		String buildingId = buyingLeadsVO.getBuildingId();
		PartnerCloudTableFilterDTO buildingFilterDTO = new PartnerCloudTableFilterDTO();
		// 组装关联关系查询filter数据筛选器，并传入公共方法
		Map<String, Object> buildingFilter = new HashMap<>(2);
		Map<String, Object> buildingQuery = new HashMap<>(2);
		buildingQuery.put("field", BuildingMessageEnum.BUILDING_ID.getFieldId());
		Map<String, Object> buildingCondition = new HashMap<>(2);
		buildingCondition.put("eq", buildingId);
		buildingQuery.put("query", buildingCondition);
		List<Object> buildingAndList = new ArrayList<>();
		buildingAndList.add(buildingQuery);
		buildingFilter.put("and", buildingAndList);
		buildingFilterDTO.setFilter(buildingFilter);
		buildingFilterDTO.setTable_id(ERPTableEnum.BUILDING_MESSAGE.getTableId());
		List<String> buildingRelations = searchAndFilterAndGetSingleRelation(buildingFilterDTO);
		multiplyBuyingLeadsDTO.setProjectId(buildingRelations);

		// 配件关联
		String relationParts = buyingLeadsVO.getRelationParts();
		PartnerCloudTableFilterDTO partsFilterDTO = new PartnerCloudTableFilterDTO();

		// 组装关联关系查询filter数据筛选器，并传入公共方法
		Map<String, Object> partsFilter = new HashMap<>(2);
		Map<String, Object> partsQuery = new HashMap<>(2);
		partsQuery.put("field", ProductInformationEnum.SYSTEM_ID.getFieldId());
		Map<String, Object> partsCondition = new HashMap<>(2);
		partsCondition.put("eq", relationParts);
		partsQuery.put("query", partsCondition);
		List<Object> andList = new ArrayList<>();
		andList.add(partsQuery);
		partsFilter.put("and", andList);
		partsFilterDTO.setFilter(partsFilter);
		partsFilterDTO.setTable_id(ERPTableEnum.PRODUCT_INFORMATION.getTableId());
		List<String> partsRelations = searchAndFilterAndGetSingleRelation(partsFilterDTO);
		multiplyBuyingLeadsDTO.setRelationParts(partsRelations);
		// 3. 传参格式转换
		Date applyDate = buyingLeadsVO.getApplyDate();
		// 若不为空，解析成字符串，YYYY-MM-DD HH:mm:ss
		if(Func.isNotEmpty(applyDate)){
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String applyDateStr = dateFormat.format(applyDate);
			multiplyBuyingLeadsDTO.setApplyDate(applyDateStr);
		}
		String partsTaskId = buyingLeadsVO.getPartsTaskId();
		String workId = buyingLeadsVO.getWorkId();
		String workSkuId = buyingLeadsVO.getWorkSkuId();
        multiplyBuyingLeadsDTO.setUnitedId(partsTaskId + "+" + workId + "+" + workSkuId);
		return multiplyBuyingLeadsDTO;
	}

	@Override
	public void syncPurchase(Long planId) {
		// 1. 查询同步字段
		BuyingLeadsVO buyingLeadsVO = maintainPartService.selectBuyingLeadsByPlanId(planId);
		PartsWorkDetailVO partsWorkDetailVO = partsWorkService.selectPartsWorkDetail(planId);

		// 2. 数据封装、处理
		if(Func.isNull(buyingLeadsVO)){
			return;
		}
		String contractTypeHistoryInfoString = buyingLeadsVO.getContractTypeHistoryInfo();
		// 将 contractTypeHistoryInfoString 转换成 MaintainContractType 对象
		if(!Func.isNull(contractTypeHistoryInfoString)){
			MaintainContractType contractTypeHistoryInfo = JSONObject.parseObject(contractTypeHistoryInfoString, MaintainContractType.class);
			if (contractTypeHistoryInfo != null) {
				List<MaintainContractType> list = new ArrayList<>(1);
				list.add(contractTypeHistoryInfo);
				List<MaintainContractType> maintainContractTypes = maintainContractTypeService.contractTypeList(list);
				String name = maintainContractTypes.get(0).getName();
				buyingLeadsVO.setContractMaintainTypeName(name);
			}
		}
		BuyingLeadsDTO buyingLeadsDTO = new BuyingLeadsDTO();
		// 2.1 固定状态字段：采购流转状态申请中、销售流转状态待报价、类型现场申请
		List<String> buyingLeadsStatus = new ArrayList<>();
		buyingLeadsStatus.add(BuyingLeadsTypeEnum.BUYING_LEADS_APPLYING.getId());
		buyingLeadsDTO.setBuyingLeadsStatus(buyingLeadsStatus);
		List<String> saleLeadsStatus = new ArrayList<>();
		saleLeadsStatus.add(BuyingLeadsTypeEnum.SALES_LEADS_QUOTING.getId());
		buyingLeadsDTO.setSaleLeadsStatus(saleLeadsStatus);
		List<String> type = new ArrayList<>();
		type.add(BuyingLeadsTypeEnum.TYPE_APPLY.getId());
		buyingLeadsDTO.setType(type);
		buyingLeadsDTO.setReceiver(buyingLeadsVO.getReceiver());
		buyingLeadsDTO.setReceiverPhone(buyingLeadsVO.getReceiverPhone());
		buyingLeadsDTO.setReceiverAddress(buyingLeadsVO.getReceiverAddress());
		buyingLeadsDTO.setPartsTaskId(buyingLeadsVO.getPartsTaskId());
		buyingLeadsDTO.setBuildingName(buyingLeadsVO.getBuildingName());
		buyingLeadsDTO.setElevatorAddress(buyingLeadsVO.getElevatorAddress());
		buyingLeadsDTO.setRequirementQuantity(buyingLeadsVO.getRequirementQuantity());
		buyingLeadsDTO.setRequirementDescription(buyingLeadsVO.getRequirementDescription());
		buyingLeadsDTO.setApplyUser(buyingLeadsVO.getApplyUser());
		buyingLeadsDTO.setElevatorAddress(buyingLeadsVO.getElevatorAddress());
		buyingLeadsDTO.setCustomer(buyingLeadsVO.getCustomer());
		if(Func.isNotBlank(buyingLeadsVO.getContractMaintainTypeName())){
			buyingLeadsDTO.setContractMaintainTypeName(buyingLeadsVO.getContractMaintainTypeName());
		}else{
			buyingLeadsDTO.setContractMaintainTypeName(buyingLeadsVO.getMaintainTypeName());
		}
		// 是否为质保梯
		String isQuaGuarantee = buyingLeadsVO.getIsQuaGuarantee();
		if(Func.isNotBlank(isQuaGuarantee) || "1".equals(isQuaGuarantee) || "0".equals(isQuaGuarantee)){
			List<String> chargeElevator = new ArrayList<>();
			if("1".equals(isQuaGuarantee)){
				chargeElevator.add(BuyingLeadsTypeEnum.IS_QUANTITY.getId());
			}else if("0".equals(isQuaGuarantee)) {
				chargeElevator.add(BuyingLeadsTypeEnum.NOT_QUANTITY.getId());
			}
			buyingLeadsDTO.setChargeElevator(chargeElevator);
		}
		// 配件清单
		if(Func.isNotBlank(buyingLeadsVO.getHUrl())){
			log.warn("开始处理并同步配件清单附件：{}", buyingLeadsVO.getHUrl());
			List<Map<String, String>> partsList = new ArrayList<>();
			Map<String, String> fileMap = new HashMap<>();
			String hUrl = buyingLeadsVO.getHUrl();
			String file_id = uploadFile(hUrl);
			fileMap.put("file_id", file_id);
			buyingLeadsDTO.setPartsList(partsList);
			if(Func.isBlank(buyingLeadsVO.getHName())){
				log.warn("配件清单文件名数据不全{}", buyingLeadsVO.getHUrl());
				buyingLeadsVO.setHName("配件清单");
			}
			fileMap.put("name", buyingLeadsVO.getHName());
			partsList.add(fileMap);
			buyingLeadsDTO.setPartsList(partsList);
		}
		// 附件
		String attachment = buyingLeadsVO.getAttachment();
		if(Func.isNotBlank(attachment)){
			log.warn("开始处理并同步附件：{}", attachment);
			List<String> urls = new ArrayList<>();
			List<String> requireKeys = new ArrayList<>();
			requireKeys.add("url");
			requireKeys.add("type");
			String requireTypeKey = "image";
			JSONArray attachmentArray = JSONArray.parseArray(attachment);
			attachmentArray.forEach(a -> {
				JSONObject attachmentObj = JSONObject.parseObject(a.toString());
				if(!attachmentObj.keySet().containsAll(requireKeys)){
					log.warn("附件数据不全：{}", attachmentObj);
					return;
				}
				String attachmentType = attachmentObj.getString("type");
				if(!requireTypeKey.equals(attachmentType)){
					return;
				}
				urls.add(attachmentObj.getString("url"));
			});
			if(Func.isNotEmpty(urls)){
				List<Map<String, String>> attachmentList = new ArrayList<>();
				urls.forEach(u -> {
					String fileName = u.substring(u.lastIndexOf("/")+1);
					String file_id = uploadFile(u);
					log.warn("上传配件附件：{}", file_id);
					Map<String, String> attachmentMap = new HashMap<>();
					attachmentMap.put("file_id", file_id);
					attachmentMap.put("name", fileName);
					attachmentList.add(attachmentMap);
				});
				buyingLeadsDTO.setAttachment(attachmentList);
			}
		}
		Date applyDate = buyingLeadsVO.getApplyDate();
		// 若不为空，解析成字符串，YYYY-MM-DD HH:mm:ss
		if(Func.isNotEmpty(applyDate)){
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String applyDateStr = dateFormat.format(applyDate);
			buyingLeadsDTO.setApplyDate(applyDateStr);
		}

		// 项目关联
		String buildingId = buyingLeadsVO.getBuildingId();
		PartnerCloudTableFilterDTO buildingFilterDTO = new PartnerCloudTableFilterDTO();
		// 组装关联关系查询filter数据筛选器，并传入公共方法
		Map<String, Object> buildingFilter = new HashMap<>(2);
		Map<String, Object> buildingQuery = new HashMap<>(2);
		buildingQuery.put("field", BuildingMessageEnum.BUILDING_ID.getFieldId());
		Map<String, Object> buildingCondition = new HashMap<>(2);
		buildingCondition.put("eq", buildingId);
		buildingQuery.put("query", buildingCondition);
		List<Object> buildingAndList = new ArrayList<>();
		buildingAndList.add(buildingQuery);
		buildingFilter.put("and", buildingAndList);
		buildingFilterDTO.setFilter(buildingFilter);
		buildingFilterDTO.setTable_id(ERPTableEnum.BUILDING_MESSAGE.getTableId());
		List<String> buildingRelations = searchAndFilterAndGetSingleRelation(buildingFilterDTO);
		buyingLeadsDTO.setProjectId(buildingRelations);

		// 配件关联
		String relationParts = buyingLeadsVO.getRelationParts();
		PartnerCloudTableFilterDTO partsFilterDTO = new PartnerCloudTableFilterDTO();

		// 组装关联关系查询filter数据筛选器，并传入公共方法
		Map<String, Object> partsFilter = new HashMap<>(2);
		Map<String, Object> partsQuery = new HashMap<>(2);
		partsQuery.put("field", ProductInformationEnum.SYSTEM_ID.getFieldId());
		Map<String, Object> partsCondition = new HashMap<>(2);
		partsCondition.put("eq", relationParts);
		partsQuery.put("query", partsCondition);
		List<Object> andList = new ArrayList<>();
		andList.add(partsQuery);
		partsFilter.put("and", andList);
		partsFilterDTO.setFilter(partsFilter);
		partsFilterDTO.setTable_id(ERPTableEnum.PRODUCT_INFORMATION.getTableId());
		List<String> partsRelations = searchAndFilterAndGetSingleRelation(partsFilterDTO);
		buyingLeadsDTO.setRelationParts(partsRelations);

		log.warn("即将上传到erp的对象：{}", buyingLeadsDTO);
		// 2025-02-14 新增 即将新增电梯品牌、唯一识别码、停梯状态字段
		buyingLeadsDTO.setElevatorBrand(buyingLeadsVO.getElevatorBrand());
		buyingLeadsDTO.setElevatorNum(buyingLeadsVO.getElevatorNum());
		buyingLeadsDTO.setElevatorStatus(buyingLeadsVO.getElevatorStatus());

		// 3. 同步数据到ERP
		PartnerCloudTableSaveOrUpdateDTO saveDTO = new PartnerCloudTableSaveOrUpdateDTO();
		// 3.1 固定信息：表id、根据配件任务id新增或更新
		saveDTO.setTable_id(ERPTableEnum.BUYING_LEADS.getTableId());
		List<String> updateFields = new ArrayList<>();
		updateFields.add(BuyingLeadsEnum.PARTS_TASK_ID.getFieldId());
		saveDTO.setUpdate_by_fields(updateFields);
		// 3.2 封装业务数据
		List<PartnerCloudTableItemDTO> items = new ArrayList<>();
		PartnerCloudTableItemDTO item = new PartnerCloudTableItemDTO();
		Map<String,Object> fields = new HashMap<>(20);
		// 固定非空非空串字段：默认状态选项、配件工单id
		fields.put(BuyingLeadsEnum.BUYING_LEADS_STATUS.getFieldId(),buyingLeadsDTO.getBuyingLeadsStatus());
		fields.put(BuyingLeadsEnum.SALES_LEADS_STATUS.getFieldId(),buyingLeadsDTO.getSaleLeadsStatus());
		fields.put(BuyingLeadsEnum.TYPE.getFieldId(),buyingLeadsDTO.getType());
		fields.put(BuyingLeadsEnum.PARTS_TASK_ID.getFieldId(),buyingLeadsDTO.getPartsTaskId());
		// 收货人信息，均可能为空，需要做判断处理
		String receiver = buyingLeadsDTO.getReceiver();
		if(StringUtil.isNotBlank(receiver)){
			fields.put(BuyingLeadsEnum.RECEIVER.getFieldId(),receiver);
		}
		String phone = buyingLeadsDTO.getReceiverPhone();
		log.warn("phone={}", phone);
		if(StringUtil.isNotBlank(phone)){
			fields.put(BuyingLeadsEnum.RECEIVER_PHONE.getFieldId(),phone);
		}
		String receiverAddress = buyingLeadsDTO.getReceiverAddress();
		if(StringUtil.isNotBlank(receiverAddress)){
			fields.put(BuyingLeadsEnum.RECEIVER_ADDRESS.getFieldId(),receiverAddress);
		}
		// 是否为质保梯
		List<String> chargeElevator = buyingLeadsDTO.getChargeElevator();
		if(Func.isNotEmpty(chargeElevator)){
			fields.put(BuyingLeadsEnum.CHARGE_ELEVATOR.getFieldId(),chargeElevator);
		}
		// 两个附件：配件清单和附件
		if(Func.isNotEmpty(buyingLeadsDTO.getPartsList())){
			fields.put(BuyingLeadsEnum.PARTS_LIST.getFieldId(),buyingLeadsDTO.getPartsList());
		}
		if(Func.isNotEmpty(buyingLeadsDTO.getAttachment())){
			fields.put(BuyingLeadsEnum.ATTACHMENT.getFieldId(),buyingLeadsDTO.getAttachment());
		}
		fields.put(BuyingLeadsEnum.BUILDING_NAME.getFieldId(),buyingLeadsDTO.getBuildingName());
		fields.put(BuyingLeadsEnum.ELEVATOR_ADDRESS.getFieldId(),buyingLeadsDTO.getElevatorAddress());
		// 2025-07 改成关联配件数量以及备注
		if(Func.isNotEmpty(partsWorkDetailVO)){
			com.alibaba.fastjson2.JSONObject finallySkuPartsInfo = partsWorkDetailVO.getFinallySkuPartsInfo();
			if(Func.isNotEmpty(finallySkuPartsInfo)){
				if(finallySkuPartsInfo.containsKey("num")){
					String num = finallySkuPartsInfo.getString("num");
					Integer numInt = Integer.parseInt(num);
					fields.put(BuyingLeadsEnum.REQUIREMENT_QUANTITY.getFieldId(),numInt);
				}
				if(finallySkuPartsInfo.containsKey("desc")){
					fields.put(BuyingLeadsEnum.REMARK.getFieldId(),finallySkuPartsInfo.get("desc"));
				}
			}
		}
		String requirementDescription = buyingLeadsDTO.getRequirementDescription();
		if(StringUtil.isNotBlank(requirementDescription)){
			fields.put(BuyingLeadsEnum.REQUIREMENT_DESCRIPTION.getFieldId(),requirementDescription);
		}
		fields.put(BuyingLeadsEnum.APPLY_DATE.getFieldId(),buyingLeadsDTO.getApplyDate());
		fields.put(BuyingLeadsEnum.APPLY_USER.getFieldId(),buyingLeadsDTO.getApplyUser());
		fields.put(BuyingLeadsEnum.CUSTOMER.getFieldId(),buyingLeadsDTO.getCustomer());
		fields.put(BuyingLeadsEnum.BUILDING_ID.getFieldId(),buyingLeadsDTO.getProjectId());
		if(Func.isNotEmpty(buyingLeadsDTO.getRelationParts())){
			fields.put(BuyingLeadsEnum.RELATION_PARTS.getFieldId(),buyingLeadsDTO.getRelationParts());
		}
		if(Func.isNotBlank(buyingLeadsDTO.getContractMaintainTypeName())){
			fields.put(BuyingLeadsEnum.MAINTAIN_TYPE_DESCRIPTION.getFieldId(),buyingLeadsDTO.getContractMaintainTypeName());
		}
		// 2025-02-14 新增 即将新增电梯品牌、唯一识别码、停梯状态字段
		if(Func.isNotBlank(buyingLeadsDTO.getElevatorBrand())){
			fields.put(BuyingLeadsEnum.ELEVATOR_BRAND.getFieldId(),buyingLeadsDTO.getElevatorBrand());
		}
		if(Func.isNotBlank(buyingLeadsDTO.getElevatorNum())){
			fields.put(BuyingLeadsEnum.ELEVATOR_NUM.getFieldId(),buyingLeadsDTO.getElevatorNum());
		}
		if(Func.isNotBlank(buyingLeadsDTO.getElevatorStatus())){
			fields.put(BuyingLeadsEnum.ELEVATOR_STATUS.getFieldId(),buyingLeadsDTO.getElevatorStatus());
		}
		item.setFields(fields);
		items.add(item);
		saveDTO.setItems(items);
		log.warn("即将上传到erp的对象：{}", saveDTO);
		boolean b = erpService.saveOrUpdateByFields(saveDTO);
		log.warn("传到erp结果：{}", b);
	}

	@Override
	public Boolean analyzeCallBackData(JSONObject resultJsonObject) {
		// 0. 数据校验，根据table_id区分是什么业务的数据,再做相应处理
		List<String> basicKeys = Arrays.asList("data", "header");
		Set<String> resultKeys = resultJsonObject.keySet();
		if(!resultKeys.containsAll(basicKeys)){
			log.error("回调数据格式错误，缺少必要字段：data 或 header");
			return false;
		}
		// 事件类型
		if("bulk_result".equals(resultJsonObject.getJSONObject("header").getString("event_type"))){
			return Boolean.TRUE;
		}
		String dataKey = "data";
		JSONObject resultData = resultJsonObject.getJSONObject(dataKey);
		JSONObject headerData = resultJsonObject.getJSONObject("header");
		Set<String> dataKeys = resultData.keySet();
		if(!dataKeys.contains("table_id") || !dataKeys.contains("bulk")){
			log.warn("解析到当前回调为非当前业务所需处理的格式回调，忽略处理");
			return false;
		}
		Long tableIdLongValue = resultData.getLong("table_id");
		String tableId = String.valueOf(tableIdLongValue);
		// 2. 根据表格id区分业务类型，并做相应处理
		if(ERPTableEnum.SALES_ORDER.getTableId().equals(tableId)){
			return this.analyzeSalesOrder(resultData, headerData);
		}
		if(ERPTableEnum.PRODUCT_SALES_ORDER.getTableId().equals(tableId)){
			return this.analyzeProductSalesOrder(resultData, headerData);
		}
		return Boolean.TRUE;
	}

	private Boolean analyzeProductSalesOrder(JSONObject resultData, JSONObject headerData) {
		// 1. 判断是否为批量回调
		Boolean bulk = resultData.getBoolean("bulk");
		if(bulk){
			if(!resultData.containsKey("item_ids")){
				return Boolean.FALSE;
			}
			JSONArray batchItemIds = resultData.getJSONArray("item_ids");
			batchItemIds.forEach(b -> {
				String itemId = b.toString();
				// 根据itemId查询发货单
				PartnerCloudTableItemVO tableItem = erpService.getTableItem(itemId);
				if(Func.isEmpty(tableItem)){
					return;
				}
				Map<String, Object> fields = tableItem.getFields();
				if(!fields.containsKey(ProductSalesOrderEnum.SEARCH_RELATION_FILED.getFieldId())){
					return;
				}
				Object salesOrderIdObject = fields.get(ProductSalesOrderEnum.SEARCH_RELATION_FILED.getFieldId());
				String salesOrderId = Convert.toStr(salesOrderIdObject);
				this.sendSalesOrderCreateMessage(salesOrderId);
			});
			return Boolean.TRUE;
		}
		else{
			// 单条创建的场景
			if(!resultData.containsKey("item")){
				return Boolean.FALSE;
			}
			JSONObject singleItemJsonObject = resultData.getJSONObject("item");
			if(!singleItemJsonObject.containsKey("fields")){
				return Boolean.FALSE;
			}
			JSONObject fields = singleItemJsonObject.getJSONObject("fields");
			if(!fields.containsKey(ProductSalesOrderEnum.SEARCH_RELATION_FILED.getFieldId())){
				log.warn("伙伴云发货单表格发生变更，无法查询销售订单以发送消息:{}", JSON.toJSONString(resultData));
				return Boolean.FALSE;
			}
			String salesOrderId = fields.getString(ProductSalesOrderEnum.SEARCH_RELATION_FILED.getFieldId());
			// 2. 调用方法，解析数据，发短信
			return this.sendSalesOrderCreateMessage(salesOrderId);
		}
	}

	private Boolean sendSalesOrderCreateMessage(String salesOrderId) {
		if(Func.isBlank(salesOrderId)){
			return Boolean.FALSE;
		}
		// 1. 组装查询条件查询销售订单
		PartnerCloudTableFilterDTO salesOrderFilterDTO = new PartnerCloudTableFilterDTO();
		salesOrderFilterDTO.setTable_id(ERPTableEnum.SALES_ORDER.getTableId());
		Map<String, Object> salesOrderFilter = new HashMap<>(2);
		List<Object> salesOrderAndList = new ArrayList<>(); // filter 内 and 列表
		Map<String, Object> salesOrderCondition = new HashMap<>(2); // and 列表对象
		Map<String, Object> salesOrderQuery = new HashMap<>(2); // and 列表对象内 具体条件查询条件对象
//		// 从内到外逐层传入对象
		List<String> orderIdEqList = new ArrayList<>(); // 最内层等于条件列表
		orderIdEqList.add(salesOrderId);
		salesOrderQuery.put("eq", orderIdEqList);
		salesOrderCondition.put("field", SalesOrderEnum.ORDER_ID.getFieldId());
		salesOrderCondition.put("query",salesOrderQuery);
		salesOrderAndList.add(salesOrderCondition);
		salesOrderFilter.put("and", salesOrderAndList);
		salesOrderFilterDTO.setFilter(salesOrderFilter);
		PartnerCloudTableItemListVO partnerCloudTableItemListVO = erpService.searchTableByCondition(salesOrderFilterDTO);
		List<PartnerCloudTableItemVO> items = partnerCloudTableItemListVO.getItems();
		items.forEach(i -> {
			Map<String, Object> fields = i.getFields();
			if(fields.containsKey(SalesOrderEnum.PARTS_ORDER_ID.getFieldId())){
				String partsOrderId = Convert.toStr(fields.get(SalesOrderEnum.PARTS_ORDER_ID.getFieldId()));
				partsWorkService.processPartsOrderMessage(partsOrderId);
			}
		});
		return Boolean.TRUE;
	}

	@Override
	@Async
	public void syncPartsSku(PartnerCloudPartsSkuSyncDTO partsSkuSyncDTO) {
		// 0. 数据校验
		List<PartnerCloudPartsSkuMessageDTO> skuList = partsSkuSyncDTO.getSkuList();
		if(Func.isEmpty(skuList)){
			return;
		}
		// 1. 解析数据，组装ERP同步数据对象
		PartnerCloudTableSaveOrUpdateDTO saveDTO = new PartnerCloudTableSaveOrUpdateDTO();
		// 3.1 固定信息：表id、根据sku id新增或更新
		saveDTO.setTable_id(ERPTableEnum.PRODUCT_INFORMATION.getTableId());
		List<String> updateFields = new ArrayList<>();
		updateFields.add(ProductInformationEnum.SYSTEM_ID.getFieldId());
		saveDTO.setUpdate_type("upsert");
		saveDTO.setUpdate_by_fields(updateFields);
		// 3.2 封装业务数据
		List<PartnerCloudTableItemDTO> items = new ArrayList<>();

		for (PartnerCloudPartsSkuMessageDTO singleSku : skuList) {
			PartnerCloudTableItemDTO item = new PartnerCloudTableItemDTO();
//			item.setItem_id(ProductInformationEnum.SYSTEM_ID.getFieldId());
			Map<String,Object> fields = new HashMap<>(20);
			// 固定非空非空串字段：配件 skuId
			fields.put(ProductInformationEnum.SYSTEM_ID.getFieldId(), singleSku.getSystemId());
			// 两组图片处理：配件图片、配件资料
			List<String> skuPictureList = singleSku.getSkuPictureList();
			if(Func.isNotEmpty(skuPictureList)){
				List<Map<String, String>> partnerCloudSKUPicture = new ArrayList<>();
				skuPictureList.forEach(s -> {
					Map<String, String> pictureMap = new HashMap<>();
					String pictureName = s.substring(s.lastIndexOf("/") + 1);
					String file_id = uploadFile(s);
					pictureMap.put("file_id", file_id);
					pictureMap.put("name", pictureName);
					partnerCloudSKUPicture.add(pictureMap);
				});
				singleSku.setPartnerCloudSKUPicture(partnerCloudSKUPicture);
				fields.put(ProductInformationEnum.PICTURE.getFieldId(), partnerCloudSKUPicture);
			}
			List<String> partsFileUrlList = singleSku.getPartsFileUrlList();
			if(Func.isNotEmpty(partsFileUrlList)) {
				List<Map<String, String>> partnerCloudPartsFile = new ArrayList<>();
				partsFileUrlList.forEach(s -> {
					Map<String, String> fileMap = new HashMap<>();
					String fileName = s.substring(s.lastIndexOf("/") + 1);
					String file_id = uploadFile(s);
					fileMap.put("file_id", file_id);
					fileMap.put("name", fileName);
					partnerCloudPartsFile.add(fileMap);
				});
				singleSku.setPartnerCloudPartsFileUrl(partnerCloudPartsFile);
				fields.put(ProductInformationEnum.PARTS_FILE_URL.getFieldId(), partnerCloudPartsFile);
			}
			// 替代兼容件关联
			List<String> skuSubstituteIdList = singleSku.getSkuSubstituteIdList();
			if(Func.isNotEmpty(skuSubstituteIdList)){
				// 组装关联关系查询filter数据筛选器，并传入公共方法
				Map<String, Object> partsFilter = new HashMap<>(2);
				Map<String, Object> partsQuery = new HashMap<>(2);
				partsQuery.put("field", ProductInformationEnum.SYSTEM_ID.getFieldId());
				Map<String, Object> partsCondition = new HashMap<>(2);
				partsCondition.put("in", skuSubstituteIdList);
				partsQuery.put("query", partsCondition);
				List<Object> andList = new ArrayList<>();
				andList.add(partsQuery);
				partsFilter.put("and", andList);
				PartnerCloudTableFilterDTO partsFilterDTO = new PartnerCloudTableFilterDTO();
				partsFilterDTO.setFilter(partsFilter);
				partsFilterDTO.setTable_id(ERPTableEnum.PRODUCT_INFORMATION.getTableId());
				List<String> partsRelations = searchAndFilterAndGetMultiRelation(partsFilterDTO);
				List<String> distinctPartsRelations = partsRelations.stream().distinct().collect(Collectors.toList());
				if(Func.isNotEmpty(partsRelations)){
					fields.put(ProductInformationEnum.SUBSTITUTE_SKU_KEY.getFieldId(), distinctPartsRelations);
				}
			}
			item.setFields(fields);
			items.add(item);
		}
		saveDTO.setItems(items);
		log.warn("即将上传到erp的对象：{}", JSON.toJSONString(saveDTO));
		boolean b = erpService.saveOrUpdateByFields(saveDTO);
		log.warn("传到erp结果：{}", b);
	}

	/**
	 * 同步上传erp的配件系统id
	 * @param partsSkuSyncDTO 上传对象
	 */
	@Override
	public void sendPartsSkuId(PartnerCloudPartsSkuSyncDTO partsSkuSyncDTO) {
		// 0. 数据校验
		List<PartnerCloudPartsSkuMessageDTO> skuList = partsSkuSyncDTO.getSkuList();
		if(Func.isEmpty(skuList)){
			return;
		}
		// 1. 解析数据，组装ERP同步数据对象
		PartnerCloudTableSaveOrUpdateDTO saveDTO = new PartnerCloudTableSaveOrUpdateDTO();
		// 3.1 固定信息：表id、根据sku id新增或更新
		saveDTO.setTable_id(ERPTableEnum.PRODUCT_INFORMATION.getTableId());
		List<String> updateFields = new ArrayList<>();
		updateFields.add(ProductInformationEnum.SYSTEM_ID.getFieldId());
		saveDTO.setUpdate_by_fields(updateFields);
		// 3.2 封装业务数据
		List<PartnerCloudTableItemDTO> items = new ArrayList<>();
		for (PartnerCloudPartsSkuMessageDTO singleSku : skuList) {
			PartnerCloudTableItemDTO item = new PartnerCloudTableItemDTO();
			Map<String,Object> fields = new HashMap<>(20);
			// 固定非空非空串字段：系统id，配件 skuId
			fields.put(ProductInformationEnum.SYSTEM_ID.getFieldId(), singleSku.getSystemId());
			// 2025-06:配件编号字段
			String skuKey = singleSku.getSkuKey();
			if(Func.isNotBlank(skuKey)){
				fields.put(ProductInformationEnum.SKU_KEY.getFieldId(), skuKey);
			}
			// 2025-06:版本号字段
			String version = singleSku.getVersion();
			if(Func.isNotBlank(version)){
				fields.put(ProductInformationEnum.VERSION.getFieldId(), version);
			}
			// 2025-06:类目属性编号，blade_sku_info表的spu_code字段拼接`code`字段
			String categoryPropertyCode = singleSku.getCategoryPropertyCode();
			if(Func.isNotBlank(categoryPropertyCode)){
				fields.put(ProductInformationEnum.CATEGORY_PROPERTY_CODE.getFieldId(), categoryPropertyCode);
			}
			// 2025-06:商品名称，blade_sku_info表的name字段
			String skuName = singleSku.getSkuName();
			if(Func.isNotBlank(skuName)){
				fields.put(ProductInformationEnum.SKU_NAME.getFieldId(), skuName);
			}
			// 2025-06:规格型号，blade_sku_info表的attr字段json处理
			String specificationAndModel = singleSku.getSpecificationAndModel();
			if(Func.isNotBlank(specificationAndModel)){
				fields.put(ProductInformationEnum.SPECIFICATION_AND_MODEL.getFieldId(), specificationAndModel);
			}
			// 2025-06:电气/机械件，直接获取中文描述
			String mechanicalTypeName = singleSku.getMechanicalTypeName();
			if(Func.isNotBlank(mechanicalTypeName)){
				fields.put(ProductInformationEnum.MECHANICAL_TYPE_NAME.getFieldId(), mechanicalTypeName);
			}
			// 2025-06:配件类型，直接获取中文描述
			String partsTypeName = singleSku.getPartsTypeName();
			if(Func.isNotBlank(partsTypeName)){
				fields.put(ProductInformationEnum.PARTS_TYPE_NAME.getFieldId(), partsTypeName);
			}
			// 2025-06: 标品、非标品
			List<String> standardTypeList = singleSku.getStandardTypeList();
			if(Func.isNotEmpty(standardTypeList)){
				fields.put(ProductInformationEnum.CATEGORY_TYPE.getFieldId(), standardTypeList);
			}
			// 类目
			String categoryName = singleSku.getCategoryName();
			if(Func.isNotBlank(categoryName)){
				fields.put(ProductInformationEnum.CATEGORY_NAME.getFieldId(), categoryName);
			}
			// 2025-06: 类型（原厂/兼容）
			String typeName = singleSku.getTypeName();
			if(Func.isNotBlank(typeName)){
				fields.put(ProductInformationEnum.TYPE_NAME.getFieldId(), typeName);
			}
			// 品牌
			String brandName = singleSku.getBrandName();
			if(Func.isNotBlank(brandName)){
				fields.put(ProductInformationEnum.BRAND_NAME.getFieldId(), brandName);
			}
			// 包装规格
			String specifications = singleSku.getSpecifications();
			if(Func.isNotBlank(specifications)){
				fields.put(ProductInformationEnum.SPECIFICATIONS.getFieldId(), specifications);
			}
			// 替代兼容件
			String substituteSkuKeyStr = singleSku.getSubstituteSkuKeyStr();
			if(Func.isNotBlank(substituteSkuKeyStr)){
				fields.put(ProductInformationEnum.SUBSTITUTE_SKU_KEY_STR.getFieldId(), substituteSkuKeyStr);
			}
			// 计量单位
			String unitName = singleSku.getUnitName();
			if(Func.isNotBlank(unitName)){
				fields.put(ProductInformationEnum.UNIT_NAME.getFieldId(), unitName);
			}
			// 替代兼容件String字段
			if(Func.isNotEmpty(singleSku.getSubstituteSkuKeyStr())){
				fields.put(ProductInformationEnum.SUBSTITUTE_SKU_KEY_STR.getFieldId(), singleSku.getSubstituteSkuKeyStr());
			}
			item.setFields(fields);
			items.add(item);
		}
		saveDTO.setItems(items);
		log.warn("即将上传到erp的对象：{}", JSON.toJSONString(saveDTO));
		boolean b = erpService.saveOrUpdateByFields(saveDTO);
		log.warn("传到erp结果：{}", b);
	}



	private Boolean analyzeSalesOrder(JSONObject resultData, JSONObject headerData) {
		String itemKey = "item";
		String batchItemKey = "item_ids";
		if(resultData.containsKey(itemKey)){
			return this.analyzeSalesOrderSingle(resultData, headerData);
		}
		if(resultData.containsKey(batchItemKey)){
			return this.analyzeSalesOrderBatch(resultData, headerData);
		}


		return Boolean.TRUE;
	}

	private Boolean analyzeSalesOrderBatch(JSONObject resultData, JSONObject headerData) {
		Boolean bulk = Boolean.FALSE;
		if(resultData.containsKey("bulk")) {
			bulk = resultData.getBoolean("bulk");
		}
		if(!bulk){
			return Boolean.FALSE;
		}
		String eventTypeKey = "event_type";
		if(!headerData.containsKey(eventTypeKey)){
			return Boolean.FALSE;
		}
		String eventType = headerData.getString(eventTypeKey);
		JSONArray itemIdsArray = resultData.getJSONArray("item_ids");
		if(Func.isEmpty(itemIdsArray)) {
			return Boolean.FALSE;
		}
		Integer targetStatus = null;
		if(!"item.update".equals(eventType)){
			targetStatus = TaskStatusEnum.PARTS_REPLY.getStatus();
		}
		int size = itemIdsArray.size();
		long sleepTime = 3000L * size;
		// 每一条等待2秒再进行查询访问
		log.warn("正在等待伙伴云生成订单id,先睡{}毫秒",sleepTime);
		try {
			Thread.sleep(sleepTime);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
		for (Object i : itemIdsArray) {
			// 通过  item id 查询 销售订单表，并将状态写回梯无忧
			String itemId = i.toString();
			PartnerCloudTableItemVO itemVO = erpService.getTableItem(itemId);
			Map<String, Object> fields = new HashMap<>(20);
			if(Func.isNotEmpty(itemVO)){
				fields = itemVO.getFields();
				// 解析当前订单状态，根据指定的值进行状态更新
				Object statusArrayObject = fields.get(SalesOrderEnum.ORDER_STATUS.getFieldId());
				// 将statusArrayObject转为JSONArray
				JSONArray statusArray = JSONArray.parseArray(JSON.toJSONString(statusArrayObject));
				if (Func.isEmpty(statusArray)){
					log.warn("伙伴云回调配件销售订单：订单状态字段为空，不做处理");
					continue;
				}
				String statusId = statusArray.getJSONObject(0).getString("id");
				// 根据statusId获取目标状态
				if(SalesOrderStatusEnum.ALL_DELIVERY.getId().equals(statusId)){
					targetStatus = TaskStatusEnum.PARTS_RECEIVE.getStatus();
				}else if(SalesOrderStatusEnum.SIGN.getId().equals(statusId)){
					targetStatus = TaskStatusEnum.PARTS_ALLOCATION.getStatus();
				}else{
					log.warn("伙伴云回调配件销售订单：订单状态字段值本次不支持，不做处理");
				}
			}
			ErpTransferStatusDTO params = new ErpTransferStatusDTO();
			Map<String,Object> param = new HashMap<>(2);
			// 订单编号
			if(Func.isNotEmpty(fields)){
				String orderId = Convert.toStr(fields.get(SalesOrderEnum.ORDER_ID.getFieldId()));
				param.put("orderId", orderId);
				// 报价单单号
				String quoteId = Convert.toStr(fields.get(SalesOrderEnum.QUOTATION_ID.getFieldId()));
				param.put("quoteId", quoteId);
				params.setParams(param);
				params.setTargetStatus(targetStatus);
				// 配件任务id列表
				List<Long> planIds = new ArrayList<>();
				String partsTaskId = Convert.toStr(fields.get(SalesOrderEnum.PARTS_ORDER_ID.getFieldId()));
				if(!Func.isNull(partsTaskId)){
					String[] split = partsTaskId.split("、");
					for (String s : split) {
						try{
							planIds.add(Long.parseLong(s));
						}catch (Exception e){
							log.error("伙伴云回调配件销售订单：配件任务id格式错误，不做处理");
							return Boolean.FALSE;
						}
					}
				}
				// 状态值
				if("item.update".equals(eventType)) {
					// 解析当前订单状态，根据指定的值进行状态更新
					if (Func.isNotEmpty(fields.get(SalesOrderEnum.ORDER_STATUS.getFieldId()))) {
						Object statusObject = fields.get(SalesOrderEnum.ORDER_STATUS.getFieldId());
						// 将statusObject转为JSONArray
						JSONArray statusArray = JSONArray.parseArray(JSON.toJSONString(statusObject));
						if (Func.isEmpty(statusArray)) {
							log.warn("伙伴云回调配件销售订单：订单状态字段为空，不做处理");
							return Boolean.FALSE;
						}
						String statusId = statusArray.getJSONObject(0).getString("id");
						// 根据statusId获取目标状态
						if (SalesOrderStatusEnum.ALL_DELIVERY.getId().equals(statusId)) {
							targetStatus = TaskStatusEnum.PARTS_RECEIVE.getStatus();
						} else if (SalesOrderStatusEnum.SIGN.getId().equals(statusId)) {
							targetStatus = TaskStatusEnum.PARTS_ALLOCATION.getStatus();
						} else {
							log.warn("伙伴云回调配件销售订单：订单状态字段值本次不支持，不做处理");
							continue;
						}
					} else {
						log.warn("伙伴云回调配件销售订单：非状态触发节点，不做处理");
						continue;
					}
				}
				params.setPlanIds(planIds);
				log.warn("强哥流程处理配件回调状态，参数:params={}", params);
				partsWorkService.erpTransferStatus(params);
			}
		}
		return Boolean.TRUE;
	}

	/**
	 * 2025-07 回调逻辑重构，判断是否为单个场景
	 * @param resultData 回调数据
	 * @param headerData 回调头信息
	 * @return 是否
	 */
	private Boolean analyzeSalesOrderSingle(JSONObject resultData, JSONObject headerData) {
		String createKey = "item.create";
		String updateKey = "item.update";
		String eventKey = "event_type";
		String itemKey = "item";
		if(!resultData.containsKey(itemKey)){
			log.warn("伙伴云回调配件销售订单：缺少item字段");
			return Boolean.FALSE;
		}
		resultData = resultData.getJSONObject(itemKey);
		String fieldsKey = "fields";
		if(!headerData.containsKey(eventKey) || !resultData.containsKey(fieldsKey)){
			log.warn("伙伴云回调配件销售订单：缺少必要字段");
			return Boolean.FALSE;
		}
		String eventType = headerData.getString(eventKey);
		JSONObject fieldsObject = resultData.getJSONObject(fieldsKey);

		Integer targetStatus = null;
		if(createKey.equals(eventType)){
			targetStatus = TaskStatusEnum.PARTS_REPLY.getStatus();
		}else if(updateKey.equals(eventType)){
			// 解析当前订单状态，根据指定的值进行状态更新
			JSONArray statusArray = fieldsObject.getJSONArray(SalesOrderEnum.ORDER_STATUS.getFieldId());
			if (Func.isEmpty(statusArray)){
				log.warn("伙伴云回调配件销售订单：订单状态字段为空，不做处理");
				return Boolean.FALSE;
			}
			String statusId = statusArray.getJSONObject(0).getString("id");
			// 根据statusId获取目标状态
			if(SalesOrderStatusEnum.ALL_DELIVERY.getId().equals(statusId)){
				targetStatus = TaskStatusEnum.PARTS_RECEIVE.getStatus();
			}else if(SalesOrderStatusEnum.SIGN.getId().equals(statusId)){
				targetStatus = TaskStatusEnum.PARTS_ALLOCATION.getStatus();
			}else{
				log.warn("伙伴云回调配件销售订单：订单状态字段值本次不支持，不做处理");
				return Boolean.FALSE;
			}
		}else{
			log.warn("伙伴云回调配件销售订单：非状态触发节点，不做处理");
			return Boolean.FALSE;
		}
		ErpTransferStatusDTO params = new ErpTransferStatusDTO();
		Map<String,Object> param = new HashMap<>(2);
		// 订单编号
		String orderId = null;
		if(fieldsObject.containsKey(SalesOrderEnum.ORDER_ID.getFieldId())){
			orderId = fieldsObject.getString(SalesOrderEnum.ORDER_ID.getFieldId());
		}
		if("自动生成无需填写".equals(orderId) || StringUtil.isBlank(orderId)){
			try {
				// 等待伙伴云生成订单号再查
				Thread.sleep(3000L);
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
			// 反查一次订单表，获取订单编号
			if(resultData.containsKey("item_id")){
				String itemId = resultData.getString("item_id");
				// 根据itemId反查伙伴云订单表获取item
				PartnerCloudTableItemVO tableItem = erpService.getTableItem(itemId);
				Map<String, Object> fields = tableItem.getFields();
				if(fields.containsKey(SalesOrderEnum.ORDER_ID.getFieldId())){
					param.put("orderId", Convert.toStr(fields.get(SalesOrderEnum.ORDER_ID.getFieldId())));
				}
			}
		}else{
			param.put("orderId", orderId);
		}
		// 报价单单号
		String quoteId = fieldsObject.getString(SalesOrderEnum.QUOTATION_ID.getFieldId());
		param.put("quoteId", quoteId);
		params.setParams(param);
		params.setTargetStatus(targetStatus);
		// 配件任务id列表
		List<Long> planIds = new ArrayList<>();
		String partsTaskId = fieldsObject.getString(SalesOrderEnum.PARTS_ORDER_ID.getFieldId());
		if(!Func.isNull(partsTaskId)){
			String[] split = partsTaskId.split("、");
			for (String s : split) {
				try{
					planIds.add(Long.parseLong(s));
				}catch (Exception e){
					log.error("伙伴云回调配件销售订单：配件任务id格式错误，不做处理");
					return Boolean.FALSE;
				}
			}
		}
		params.setPlanIds(planIds);
		log.warn("强哥流程处理配件回调状态，参数:params={}", params);
		partsWorkService.erpTransferStatus(params);
		return Boolean.TRUE;
	}

	/**
	 * 下载文件
	 * @param fileUrl 文件URL
	 * @return File
	 */
	public File downloadFile(String fileUrl) throws IOException {
		// 构建URL对象
		URL url = new URL(fileUrl);
		// 打开连接
		try (InputStream in = url.openStream()) {
			// 获取项目根目录
			String projectPath = System.getProperty("user.dir");
			// 获取文件名
			String fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
			// 连接文件路径和文件名
			Path localFilePath = Paths.get(projectPath, fileName);
			// 下载文件到本地
			Files.copy(in, localFilePath, StandardCopyOption.REPLACE_EXISTING);
			return localFilePath.toFile();
		}catch (IOException e) {
			log.error("下载文件失败", e);
			return null;
		}
	}

	public void deleteLocalFile(Path filePath) throws IOException {
		// 删除本地文件
		Files.delete(filePath);
		log.info("Target file is uploaded and local file is deleted.");
	}

	public String uploadFile(String fileUrl){
		try {
			File file = downloadFile(fileUrl);
			String s = erpService.uploadFile(file);
			deleteLocalFile(file.toPath());
			log.warn("文件上传结果：{}",s);
			return s;
		} catch (IOException e) {
			log.error("下载文件失败", e);
			return null;
		}
	}

	private List<String> searchAndFilterAndGetSingleRelation(PartnerCloudTableFilterDTO filterDTO){
		PartnerCloudTableItemListVO targetRelation = erpService.searchTableByCondition(filterDTO);
		List<PartnerCloudTableItemVO> relationItems = targetRelation.getItems();
		List<String> itemIds = new ArrayList<>();
		if(Func.isNotEmpty(relationItems)){
			PartnerCloudTableItemVO targetRelationVO = relationItems.get(0);
			String itemId = targetRelationVO.getItem_id();
			itemIds.add(itemId);
		}
		return itemIds;
	}

	private List<String> searchAndFilterAndGetMultiRelation(PartnerCloudTableFilterDTO filterDTO){
		PartnerCloudTableItemListVO targetRelation = erpService.searchTableByCondition(filterDTO);
		List<PartnerCloudTableItemVO> relationItems = targetRelation.getItems();
		List<String> itemIds = new ArrayList<>();
		if(Func.isNotEmpty(relationItems)){
			relationItems.forEach(r -> itemIds.add(r.getItem_id()));
		}
		return itemIds;
	}


	@Override
	public List<SalesOrderSearchVO> searchOrderByOrderId(String orderId) {
		List<SalesOrderSearchVO> searchResult;
	    searchResult = this.searchOrderMainByOrderId(orderId);
		if(Func.isEmpty(searchResult)){
			return searchResult;
		}
		searchResult.forEach(s -> {
			List<DeliveryVO> deliveryList = this.searchDeliveryByOrderId(orderId);
			if(Func.isNotEmpty(deliveryList)){
				deliveryList.forEach(
					d ->{
						String deliveryNote = d.getDeliveryNote();
						if(Func.isNotBlank(deliveryNote)){
							d.setShipmentDetailList(this.searchShipmentDetailByDeliveryNote(deliveryNote));
						}
					}
				);
			}
			s.setDeliveryList(deliveryList);
		});
		return searchResult;
	}

	@Override
	public List<DeliveryVO> searchDeliveryByOrderId(String orderId) {
		List<DeliveryVO> deliveryList = new ArrayList<>();
		// 1. 根据orderId，组装条件并查询伙伴云
		PartnerCloudTableFilterDTO productSalesOrderFilterDTO = new PartnerCloudTableFilterDTO();
		productSalesOrderFilterDTO.setTable_id(ERPTableEnum.PRODUCT_SALES_ORDER.getTableId());
		Map<String, Object> productSalesOrderFilter = new HashMap<>(2);
		List<Object> productSalesOrderAndList = new ArrayList<>(); // filter 内 and 列表
		Map<String, Object> productSalesOrderCondition = new HashMap<>(2); // and 列表对象
		Map<String, Object> salesOrderQuery = new HashMap<>(2); // and 列表对象内 具体条件查询条件对象
		// 从内到外逐层传入对象
		List<String> salesOrderEqList = new ArrayList<>(); // 最内层等于条件列表
		salesOrderEqList.add(orderId);
		salesOrderQuery.put("eq", salesOrderEqList);
		productSalesOrderCondition.put("field", ProductSalesOrderEnum.SEARCH_RELATION_FILED.getFieldId());
		productSalesOrderCondition.put("query",salesOrderQuery);
		productSalesOrderAndList.add(productSalesOrderCondition);
		productSalesOrderFilter.put("and", productSalesOrderAndList);
		productSalesOrderFilterDTO.setFilter(productSalesOrderFilter);
		PartnerCloudTableItemListVO partnerCloudTableItemListVO = erpService.searchTableByCondition(productSalesOrderFilterDTO);
		if(Func.isEmpty(partnerCloudTableItemListVO) || Func.isEmpty(partnerCloudTableItemListVO.getItems())){
			log.warn("未查询到伙伴云发货单表信息，orderId={}", orderId);
			return deliveryList;
		}
		List<PartnerCloudTableItemVO> productSalesOrderItems = partnerCloudTableItemListVO.getItems();
		productSalesOrderItems.forEach( p ->{
			DeliveryVO deliveryVO = new DeliveryVO();
			Map<String, Object> fields = p.getFields();
			if(fields.containsKey(ProductSalesOrderEnum.STATUS.getFieldId())){
				Object productOrderStatusObject = fields.get(ProductSalesOrderEnum.STATUS.getFieldId());
				List<?> productOrderStatusList = Convert.toList(Map.class, productOrderStatusObject);
				if(Func.isEmpty(productOrderStatusList) || productOrderStatusList.size() > 1){
					throw new ServiceException("伙伴云发货单表中订单状态字段解析异常(伙伴云字段发生变更)，请联系管理员");
				}
				Map<String, String> productOrderStatusMap = Convert.toMap(String.class, String.class, productOrderStatusList.get(0));
				if(productOrderStatusMap.containsKey("id")){
					deliveryVO.setStatus(Convert.toStr(productOrderStatusMap.get("id")));
				}
				if(productOrderStatusMap.containsKey("name")){
					deliveryVO.setStatusName(Convert.toStr(productOrderStatusMap.get("name")));
				}
			}
			if(fields.containsKey(ProductSalesOrderEnum.REQUEST_DATE.getFieldId())){
				deliveryVO.setRequestDate(Convert.toStr(fields.get(ProductSalesOrderEnum.REQUEST_DATE.getFieldId())));
			}
			if(fields.containsKey(ProductSalesOrderEnum.ACTUAL_DATE.getFieldId())){
				deliveryVO.setActualDate(Convert.toStr(fields.get(ProductSalesOrderEnum.ACTUAL_DATE.getFieldId())));
			}
			if(fields.containsKey(ProductSalesOrderEnum.SHIPPING_METHOD.getFieldId())){
				Object shippingMethodObject = fields.get(ProductSalesOrderEnum.SHIPPING_METHOD.getFieldId());
				List<?> shippingMethodList = Convert.toList(Map.class, shippingMethodObject);
				if(Func.isEmpty(shippingMethodList) || shippingMethodList.size() > 1){
					log.warn("伙伴云发货单表中运输方式字段解析异常(伙伴云字段发生变更)，请联系管理员");
				}
				Map<String, String> shippingMethodMap = Convert.toMap(String.class, String.class, shippingMethodList.get(0));
				if(shippingMethodMap.containsKey("name")){
					deliveryVO.setShippingMethod(Convert.toStr(shippingMethodMap.get("name")));
				}
			}
			if(fields.containsKey(ProductSalesOrderEnum.SHIPPER.getFieldId())){
				Object shipperObject = fields.get(ProductSalesOrderEnum.SHIPPER.getFieldId());
				List<?> shipperList = Convert.toList(Map.class, shipperObject);
				if(Func.isEmpty(shipperList) || shipperList.size() > 1){
					log.warn("伙伴云发货单表中发货人字段解析异常(伙伴云字段发生变更)，请联系管理员");
				}
				Map<String, String> shipperMap = Convert.toMap(String.class, String.class, shipperList.get(0));
				if(shipperMap.containsKey("name")){
					deliveryVO.setShipper(Convert.toStr(shipperMap.get("name")));
				}
			}
			if(fields.containsKey(ProductSalesOrderEnum.TRACKING_NUMBER.getFieldId())){
				deliveryVO.setTrackingNumber(Convert.toStr(fields.get(ProductSalesOrderEnum.TRACKING_NUMBER.getFieldId())));
			}
			if(fields.containsKey(ProductSalesOrderEnum.DELIVERY_NOTE.getFieldId())){
				Object deliveryNoteObject = fields.get(ProductSalesOrderEnum.DELIVERY_NOTE.getFieldId());
				List<?> deliveryNoteList = Convert.toList(Map.class, deliveryNoteObject);
				if(Func.isEmpty(deliveryNoteList) || deliveryNoteList.size() > 1){
					log.warn("伙伴云发货单表deliveryNote字段解析异常(伙伴云字段发生变更)，请联系管理员");
				}
				Map<String, String> deliveryNotMap = Convert.toMap(String.class, String.class, deliveryNoteList.get(0));
				if(deliveryNotMap.containsKey("title")){
					String deliveryDetail = deliveryNotMap.get("title");
					String[] detailIdList = deliveryDetail.split(" ");
					deliveryVO.setDeliveryNote(detailIdList[0]);
				}
			}
			deliveryList.add(deliveryVO);
		});

		return deliveryList;
	}

	@Override
	public List<ShipmentDetailVO> searchShipmentDetailByDeliveryNote(String deliveryNote) {
		List<ShipmentDetailVO> shipmentDetailList = new ArrayList<>();
		if(Func.isBlank(deliveryNote)){
			return shipmentDetailList;
		}
		// 组装查询条件
		PartnerCloudTableFilterDTO shipmentDetailFilterDTO = new PartnerCloudTableFilterDTO();
		shipmentDetailFilterDTO.setTable_id(ERPTableEnum.PRODUCT_SALES_ORDER_DETAIL.getTableId());
		Map<String, Object> shipmentDetailFilter = new HashMap<>(2);
		List<Object> shipmentDetailAndList = new ArrayList<>(); // filter 内 and 列表
		Map<String, Object> shipmentDetailCondition = new HashMap<>(2); // and 列表对象
		Map<String, Object> shipmentDetailQuery = new HashMap<>(2); // and 列表对象内 具体条件查询条件对象
		// 从内到外逐层传入对象
		List<String> deliveryNoteEqList = new ArrayList<>(); // 最内层等于条件列表
		deliveryNoteEqList.add(deliveryNote);
		shipmentDetailQuery.put("eq", deliveryNoteEqList);
		shipmentDetailCondition.put("field", ProductSalesOrderDetailEnum.SEARCH_RELATION_FILED.getFieldId());
		shipmentDetailCondition.put("query",shipmentDetailQuery);
		shipmentDetailAndList.add(shipmentDetailCondition);
		shipmentDetailFilter.put("and", shipmentDetailAndList);
		shipmentDetailFilterDTO.setFilter(shipmentDetailFilter);
		PartnerCloudTableItemListVO partnerCloudTableItemListVO = erpService.searchTableByCondition(shipmentDetailFilterDTO);
		if(Func.isEmpty(partnerCloudTableItemListVO) || Func.isEmpty(partnerCloudTableItemListVO.getItems())){
			log.warn("未查询到伙伴云发货单明细表信息，deliveryNote={}", deliveryNote);
			return shipmentDetailList;
		}
		List<PartnerCloudTableItemVO> shipmentDetailItems = partnerCloudTableItemListVO.getItems();
		shipmentDetailItems.forEach(s -> {
			ShipmentDetailVO shipmentDetailVO = new ShipmentDetailVO();
			Map<String, Object> fields = s.getFields();
			if(fields.containsKey(ProductSalesOrderDetailEnum.IMAGE_URL.getFieldId())){
				Object imageUrlObject = fields.get(ProductSalesOrderDetailEnum.IMAGE_URL.getFieldId());
				List<?> imageUrlList = Convert.toList(Map.class, imageUrlObject);
				List<String> imageUrlResultList = new ArrayList<>();
				imageUrlList.forEach(i -> {
					Map<String, Object> imageUrlMap = Convert.toMap(String.class, Object.class, i);
					if(imageUrlMap.containsKey("link")){
						Object linkObject = imageUrlMap.get("link");
						Map<String, Object> linkMap = Convert.toMap(String.class, Object.class, linkObject);
						if(linkMap.containsKey("source")){
							imageUrlResultList.add(Convert.toStr(linkMap.get("source")));
						}
					}
				});
				if(Func.isNotEmpty(imageUrlResultList)){
					shipmentDetailVO.setImageUrl(imageUrlResultList);
				}
			}
			if(fields.containsKey(ProductSalesOrderDetailEnum.PART_NUMBER.getFieldId())){
				shipmentDetailVO.setPartNumber(Convert.toStr(fields.get(ProductSalesOrderDetailEnum.PART_NUMBER.getFieldId())));
			}
			if(fields.containsKey(ProductSalesOrderDetailEnum.PART_NAME.getFieldId())){
				shipmentDetailVO.setPartName(Convert.toStr(fields.get(ProductSalesOrderDetailEnum.PART_NAME.getFieldId())));
			}
			if(fields.containsKey(ProductSalesOrderDetailEnum.MODEL.getFieldId())){
				shipmentDetailVO.setModel(Convert.toStr(fields.get(ProductSalesOrderDetailEnum.MODEL.getFieldId())));
			}
			if(fields.containsKey(ProductSalesOrderDetailEnum.QUANTITY.getFieldId())){
				shipmentDetailVO.setQuantity(Convert.toDouble(fields.get(ProductSalesOrderDetailEnum.QUANTITY.getFieldId())));
			}
			if(fields.containsKey(ProductSalesOrderDetailEnum.UNIT.getFieldId())) {
				shipmentDetailVO.setUnit(Convert.toStr(fields.get(ProductSalesOrderDetailEnum.UNIT.getFieldId())));
			}
			shipmentDetailList.add(shipmentDetailVO);
		});
		return shipmentDetailList;
	}

	@Override
	public List<SalesOrderSearchVO> searchOrderMainByOrderId(String orderId) {
		// 0. 定义返回对象
		List<SalesOrderSearchVO> searchResult = new ArrayList<>();
		// 1. 根据伙伴云文档https://openapi.huoban.com/api-17851170 构建查询条件查询销售订单主表列表
		PartnerCloudTableFilterDTO salesOrderFilterDTO = new PartnerCloudTableFilterDTO();
		salesOrderFilterDTO.setTable_id(ERPTableEnum.SALES_ORDER.getTableId());
		Map<String, Object> salesOrderFilter = new HashMap<>(2);
		List<Object> salesOrderAndList = new ArrayList<>(); // filter 内 and 列表
		Map<String, Object> salesOrderCondition = new HashMap<>(2); // and 列表对象
		Map<String, Object> salesOrderQuery = new HashMap<>(2); // and 列表对象内 具体条件查询条件对象
		// 从内到外逐层传入对象
		List<String> salesOrderEqList = new ArrayList<>(); // 最内层等于条件列表
		salesOrderEqList.add(orderId);
		salesOrderQuery.put("eq", salesOrderEqList);
		salesOrderCondition.put("field", SalesOrderEnum.ORDER_ID.getFieldId());
		salesOrderCondition.put("query",salesOrderQuery);
		salesOrderAndList.add(salesOrderCondition);
		salesOrderFilter.put("and", salesOrderAndList);
		salesOrderFilterDTO.setFilter(salesOrderFilter);
		PartnerCloudTableItemListVO partnerCloudTableItemListVO = erpService.searchTableByCondition(salesOrderFilterDTO);
		if(Func.isEmpty(partnerCloudTableItemListVO) || Func.isEmpty(partnerCloudTableItemListVO.getItems())){
			log.warn("未查询到伙伴云销售订单主表信息，orderId={}", orderId);
		}
		// 1.2 解析Items, 主表赋值
		List<PartnerCloudTableItemVO> salesOrderItems = partnerCloudTableItemListVO.getItems();
		salesOrderItems.forEach(
			i -> {
				SalesOrderSearchVO searchVO = new SalesOrderSearchVO();
				// 匹配返回对象中的key并赋值
				Map<String, Object> fields = i.getFields();
				if(fields.containsKey(SalesOrderEnum.ORDER_ID.getFieldId())){
					searchVO.setOrderId(Convert.toStr(fields.get(SalesOrderEnum.ORDER_ID.getFieldId())));
				}
				if(fields.containsKey(SalesOrderEnum.ORDER_STATUS.getFieldId())){
					Object orderStatusObject = fields.get(SalesOrderEnum.ORDER_STATUS.getFieldId());
					List<?> orderStatusList = Convert.toList(Map.class, orderStatusObject);
					if(Func.isEmpty(orderStatusList) || orderStatusList.size() > 1){
						throw new ServiceException("伙伴云销售订单主表中订单状态字段解析异常(伙伴云字段发生变更)，请联系管理员");
					}
					Map<String, String> orderStatusMap = Convert.toMap(String.class, String.class, orderStatusList.get(0));
					if(orderStatusMap.containsKey("id")){
						searchVO.setOrderStatus(orderStatusMap.get("id"));
					}
					if(orderStatusMap.containsKey("name")){
						searchVO.setOrderStatusName(orderStatusMap.get("name"));
					}
				}
				if(fields.containsKey(SalesOrderEnum.QUOTE_ID.getFieldId())){
					searchVO.setQuoteId(Convert.toStr(fields.get(SalesOrderEnum.QUOTE_ID.getFieldId())));
				}
				if(fields.containsKey(SalesOrderEnum.ORDER_DATE.getFieldId())){
					searchVO.setOrderDate(Convert.toStr(fields.get(SalesOrderEnum.ORDER_DATE.getFieldId())));
				}
				if(fields.containsKey(SalesOrderEnum.ACTUAL_DELIVERY_DATE.getFieldId())){
					searchVO.setActualDeliveryDate(Convert.toStr(fields.get(SalesOrderEnum.ACTUAL_DELIVERY_DATE.getFieldId())));
				}
				if(fields.containsKey(SalesOrderEnum.SALES_PERSON.getFieldId())){
					Object salesPersonObject = fields.get(SalesOrderEnum.SALES_PERSON.getFieldId());
					List<?> salsePersonList = Convert.toList(Map.class, salesPersonObject);
					if(Func.isEmpty(salsePersonList) || salsePersonList.size() > 1){
						throw new ServiceException("伙伴云销售订单主表中销售（商务人员）字段解析异常(伙伴云字段发生变更)，请联系管理员");
					}
					Map<String, String> salesPersonMap = Convert.toMap(String.class, String.class, salsePersonList.get(0));
					if(salesPersonMap.containsKey("name")){
						searchVO.setSalesPerson(salesPersonMap.get("name"));
					}
				}
				if(fields.containsKey(SalesOrderEnum.RECIPIENT_NAME.getFieldId())){
					searchVO.setRecipientName(Convert.toStr(fields.get(SalesOrderEnum.RECIPIENT_NAME.getFieldId())));
				}
				if(fields.containsKey(SalesOrderEnum.RECIPIENT_ADDRESS.getFieldId())){
					searchVO.setRecipientAddress(Convert.toStr(fields.get(SalesOrderEnum.RECIPIENT_ADDRESS.getFieldId())));
				}
				if(fields.containsKey(SalesOrderEnum.RECIPIENT_PHONE.getFieldId())){
					searchVO.setRecipientPhone(Convert.toStr(fields.get(SalesOrderEnum.RECIPIENT_PHONE.getFieldId())));
				}
				searchResult.add(searchVO);
			}
		);
		return searchResult;
	}




}
